package com.mao.crowd.mvc.config;

import com.google.gson.Gson;
import com.mao.crowd.constant.CrowdConstant;
import com.mao.crowd.exception.EditAcctDuplicatedException;
import com.mao.crowd.exception.LoginAcctDuplicatedException;
import com.mao.crowd.exception.LoginFailException;
import com.mao.crowd.util.CrowdUtil;
import com.mao.crowd.util.ResultEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 基于注解的异常映射类
 *
 * @author maomeng
 * @create 2021-05-27- 17:47
 */
@ControllerAdvice
public class CrowdExceptionResolver {

    @ExceptionHandler(value = EditAcctDuplicatedException.class)
    public ModelAndView resolveEditAcctDuplicatedException(EditAcctDuplicatedException exception, HttpServletRequest request, HttpServletResponse response) throws IOException {
        String viewName = "system-error";
        return commonResolve(viewName,exception,request,response);
    }

    @ExceptionHandler(value = LoginAcctDuplicatedException.class)
    public ModelAndView resolveLoginAcctDuplicatedException(LoginAcctDuplicatedException exception, HttpServletRequest request, HttpServletResponse response) throws IOException {

        String viewName = "admin-add";
        return commonResolve(viewName,exception,request,response);
    }

    @ExceptionHandler(value = LoginFailException.class)
    public ModelAndView resolveLoginFailedException(LoginFailException exception, HttpServletRequest request, HttpServletResponse response) throws IOException {
        String viewName = "admin-login";
        return commonResolve(viewName,exception,request,response);
    }

    @ExceptionHandler(value = Exception.class)
    public ModelAndView resolveException(Exception exception, HttpServletRequest request, HttpServletResponse response) throws IOException {
        String viewName = "admin-login";
        return commonResolve(viewName,exception,request,response);
    }


    /**
     *
     * @param exception 实际捕获到的异常类型
     * @param request 当前请求对象
     * @param response 当前响应对象
     * @return 空指针异常对应ModelAndView
     * @throws IOException
     */
    @ExceptionHandler(value = NullPointerException.class)
    //    ExceptionHandler用来关联当前方法和一个具体的异常类
    public ModelAndView resolveNullPointerException(NullPointerException exception, HttpServletRequest request, HttpServletResponse response) throws IOException {
        String viewName = "system-error";
        return commonResolve(viewName,exception,request,response);
    }

    /**
     *
     * @param viewName 返回的异常页面名
     * @param exception 实际捕获到的异常类型
     * @param request 当前请求对象
     * @param response 当前响应对象
     * @return 异常页面modelAndView
     * @throws IOException
     */
    private static ModelAndView commonResolve(String viewName, Exception exception, HttpServletRequest request, HttpServletResponse response) throws IOException {
        //        调用是否是ajax请求的判断
        boolean isAjax = CrowdUtil.judgeRequestType(request);
        if (isAjax) {
//            统一的ajax请求返回类型,方法:failed
            ResultEntity<Object> resultEntity = ResultEntity.failed(exception.getMessage());
//            调用gosn把resultEntity转成json
            Gson gson = new Gson();
            String json = gson.toJson(resultEntity);
//            将转换成的json对象写入response响应对象
            response.getWriter().write(json);
            return null;
        }
//        如果不是ajax异常,就直接把异常装配进modelandView对象
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject(CrowdConstant.ATTR_NAME_EXCEPTION, exception);
        modelAndView.setViewName(viewName);
        return modelAndView;
    }

}
